package org.mathcloud.math.io.string.generic;

import java.io.File;

import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import org.mathcloud.math.core.common.quantity.ComplexNumber;
import org.mathcloud.math.core.common.quantity.MatrixObject;
import org.mathcloud.math.core.common.quantity.QuantityObject;
import org.mathcloud.math.core.common.quantity.RealMatrix;
import org.mathcloud.math.core.common.quantity.RealNumber;
import org.mathcloud.math.io.json.common.JSONQuantityObjectOutputter;
import org.mathcloud.math.io.string.common.StringQuantityObjectOutputter;
import org.mathcloud.math.io.utility.generic.GenericFileUtility;


public class GenericOutputter implements StringQuantityObjectOutputter, JSONQuantityObjectOutputter
{
	@Override
	public String output(QuantityObject in)
	{
		if (in==null)
			return null;
		else if (in.getSignature().isRealNumberSignature())
			return outputRealNumber((RealNumber)in);
		else if (in.getSignature().isComplexNumberSignature())
			return outputComplexNumber((ComplexNumber)in);
		else if (in.getSignature().isMatrix())
			return outputMatrix((MatrixObject)in, null, null);
		else return null;
	}

	public String outputRealNumber(RealNumber arg0)
	{
		return String.valueOf(arg0.getValue());
	}
	
	public String outputComplexNumber(ComplexNumber arg0)
	{
		String res;
		res = String.valueOf(((ComplexNumber)arg0).getRealPart());
		if (((ComplexNumber)arg0).getImagePart()>0)
			res = res + "+" + String.valueOf(((ComplexNumber)arg0).getImagePart())+"i";
		else if (((ComplexNumber)arg0).getImagePart()<0)
			res = res + String.valueOf(((ComplexNumber)arg0).getImagePart())+"i";
		return res;
	}

	public String outputMatrix(MatrixObject arg0, String rowSep, String colSep)
	{
		String res;
		String trowSep = (rowSep!=null)?rowSep:"\n";
		String tcolSep = (colSep!=null)?colSep:"\t"; 

		String tRes = output(arg0.getMatrixElement(0,0));
		for (int j=1;j<arg0.getSignature().getDimensions()[1];j++)
		{
			tRes = tRes + tcolSep + output(arg0.getMatrixElement(0,j));					
		}
		res = tRes+trowSep;
		for (int i=1;i<arg0.getSignature().getDimensions()[0];i++)
		{
			tRes = output(((MatrixObject)arg0).getMatrixElement(i,0));
			for (int j=1;j<arg0.getSignature().getDimensions()[1];j++)
			{
				tRes = tRes + tcolSep + output(((MatrixObject)arg0).getMatrixElement(i,j));					
			}
			tRes = tRes+trowSep;
			res = res + tRes;
		}						
		return res;		
	}	
	
	public File outputMatrix(String fileName, MatrixObject arg0, String rowSep, String colSep)
	{
		String out = outputMatrix(arg0, rowSep, colSep);
		GenericFileUtility.string2File(fileName, out, null);
  	File res = new File(fileName);
  	if (res.exists())
  		return res;
  	else return null;
	}

	@Override
	public JSONObject output(String key, QuantityObject arg0) throws JSONException
	{
		JSONObject res = new JSONObject();
		if (arg0.getSignature().isRealNumberSignature())
		{
			res.put(key, ((RealNumber)arg0).getValue());
		}
		else if (arg0.getSignature().isRealMatrixSignature())
		{
			JSONArray row = new JSONArray();
			JSONArray col;
			RealNumber r;
			for (int i=0;i<arg0.getSignature().getDimensions()[0];i++)
			{
				col = new JSONArray();
				for (int j=0;j<arg0.getSignature().getDimensions()[1];j++)
				{ 					
					r = (RealNumber)((RealMatrix)arg0).getMatrixElement(i, j);
					col.put(j,r.getValue());
				}
				row.put(i,col);
			}
			res.put(key, row);
		}
		else
		{
			res.put(key,0);		// json presentation of complex number should be defined
		}
		return res;
	}

}
